ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Been trying to figure this one out for about a day now. Basically, my program gets so far to sending and receiving data, but at the same point, send() comes back as "-1" and says that the connection was reset by the peer. I'm not sure why this is, as the code was working fine before I put in some code for reading the buffer size first. It seems to be that the server is sending data faster than the client receives it, would using sleep(1) after each sendall() be a better idea to stop the race condition?
Edit I should also mention that this isn't using select() for asynch sockets, just using a fork() call instead. /Edit
Edit 2 Sorry for the bumping (if edits cause this). But, following a trace of tcpdump, the RST flag is being set and I'm not sure why, as the socket isn't being closed anywhere near the code.[/b]
Here's the code in question:
Network code:
Code:
/**
* sendall()
* s: Socket [file descriptor] to send data to [in]
* buffer: The data to send to the socket [in]
*
* Recursive send() for socket, since TCP/IP can't guarantee all of buffer will be sent in one go.
*
* Returns 0 on failure, otherwise total bytes sent.
**/
int sendall(int s, char *buffer){
int pos = 0;
int len = strlen(buffer);
int left = len;
int curr = 0;
while(pos < len){
D(("socket = %d, pos = %d, left = %d", s, pos, left));
curr = send(s, buffer+pos, left, 0);
if(curr == -1){
D(("error = %d", errno));
perror("send()");
return 0;
}
D(("curr = %d", curr));
pos += curr;
left -= curr;
}
memset(&buffer, '\0', strlen(buffer));
return pos;
}
int recvbufflen(int s){
char *tmp = (char*)malloc(sizeof(char) * 5);
memset(tmp, '\0', sizeof(tmp));
recv(s, tmp, 5, 0);
int len = atoi(tmp);
free(tmp);
return len;
}
void sendbufflen(int s, int len){
char *tmp = (char*)malloc(sizeof(char) * 5);
memset(tmp, '\0', sizeof(tmp));
D(("strlen = %d", len));
sprintf(tmp, "%05d", len);
if(!sendall(s, tmp))
D(("error sendbufflen() -> sendall()"));
free(tmp);
}
Server code:
Code:
// Get the client's B value
bufflen = recvbufflen(connfd);
recv(connfd, buff, bufflen, 0);
str2mpz(buff, B);
// Tell the client our A value
sendbufflen(connfd, strlen(szA));
sendall(connfd, szA);
// We generate our secret key with the same formulas as A
mpz_powm_sec(Ssk, B, Ss, P);
// Tell the client the key size of the Viegnere Cipher (26, 54, or 96)
sprintf(buff, "%d", vhkey);
sendbufflen(connfd, strlen(buff));
sendall(connfd, buff);
Clinet code (causing the reset for some reason):
Code:
// B = (G ^ Cs)(mod P)
mpz_powm_sec(B, G, Cs, P);
mpz2str(B, szB);
// Tell the server what our B value is
sendbufflen(sockfd, strlen(szB));
D(("sockfd = %d", sockfd));
sendall(sockfd, szB);
// Get the server's A value
bufflen = recvbufflen(sockfd);
D(("bufflen = %d", bufflen));
recv(sockfd, buff, bufflen, 0);
str2mpz(buff, A);
D(("HI!"));
D((...)) is a macro for debugging code (uses printf()).
Last edited by raevin; 07-22-2011 at 08:19 AM.
Reason: Reset flag is being set
In your sendall() function, I believe the following is a bug:
Code:
memset(&buffer, '\0', strlen(buffer));
The 'buffer' is already a pointer to a location in memory, thus you do not need to pass it's address to memset(). What you want memset() to do is clear the string being pointed to by 'buffer'; instead you are clearing the memory location, and then possibly some additional memory (depending on the length of the string), with the code above.
I would also recommend that you perform error checking when calling recv(). You may not necessarily receive all of the data you expect with merely one call.
In your sendall() function, I believe the following is a bug:
Code:
memset(&buffer, '\0', strlen(buffer));
The 'buffer' is already a pointer to a location in memory, thus you do not need to pass it's address to memset(). What you want memset() to do is clear the string being pointed to by 'buffer'; instead you are clearing the memory location, and then possibly some additional memory (depending on the length of the string), with the code above.
I would also recommend that you perform error checking when calling recv(). You may not necessarily receive all of the data you expect with merely one call.
Didn't think it was a bug, but I fixed it anyways, thanks! As for doing error checking on recv(), it works when I don't do use the below code to capture all the buffer data, but when I do the below code, it hangs at recv() for some reason:
Code:
int recvall(int s, char *buffer, int len){
D(("Receiving %d bytes from %d", len, s));
int curr = 0;
int pos = 0;
int left = len;
/**
* If we weren't using blocking I/O for sockets, could do "!= 0" instead...
* However, "-1" is the only check possible right now...
**/
while(pos < len){
D(("while(%d < %d)", pos, len));
curr = recv(s, buffer+pos, left, 0);
if(curr == -1){
perror("recvall()");
pos = 0;
break;
}
pos += curr;
left -= curr;
D(("Read %d bytes (%d / %d total)", curr, pos, len));
}
return pos;
}
This is a blocking system, but I just find it weird that it works when its not inside of a while() loop, but doesn't as soon as I put it inside of one.
When calling recv(), the return value of -1 is not necessarily indicative of a "fatal" error. Check the value of errno; if it is EINTR or EAGAIN (or EWOULDBLOCK), then I would suggest that you return to the top of the loop.
P.S. Personally, I always use select() to determine when it is appropriate to call recv().
Last edited by dwhitney67; 07-22-2011 at 09:22 AM.
When calling recv(), the return value of -1 is not necessarily indicative of a "fatal" error. Check the value of errno; if it is EINTR or EAGAIN (or EWOULDBLOCK), then I would suggest that you return to the top of the loop.
P.S. Personally, I always use select() to determine when it is appropriate to call recv().
I'll do that then, and see what happens. Just whenever I read about recv() it says that -1 is error, but never thought to check errno. Also, doesn't select() only work for asynch sockets?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.